package main

import (
	"bytes"
	"database/sql"
	"encoding/binary"
	"encoding/hex"
	"fmt"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"time"

	_ "github.com/go-sql-driver/mysql"
	"github.com/gorilla/websocket"
)

const (
	FrameHeader = 0xA55A
	FrameTail   = 0xCC33C33C
)

// WebSocket升级器
var upgrader = websocket.Upgrader{
	ReadBufferSize:  1024,
	WriteBufferSize: 1024,
	CheckOrigin: func(r *http.Request) bool {
		return true
	},
}

// 保存所有连接的WebSocket客户端
var clients = make(map[*websocket.Conn]bool)

// 广播通道
var broadcast = make(chan []byte)

type Frame struct {
	Header       uint16
	Length       uint8
	Manufacturer uint8
	Version      uint8
	FrameType    uint8
	DeviceID     [4]byte
	Info         []byte
	Checksum     uint8
	Tail         uint32
}

type DeviceAttributes struct {
	SIMCard          string
	GroupID          uint16
	TowerInGroup     uint16
	RopeRate         uint8
	XCoordinate      float32
	YCoordinate      float32
	FrontArmLength   float32
	RearArmLength    float32
	TowerCapHeight   float32
	TowerBodyHeight  float32
	Longitude        float64
	Latitude         float64
	MaxLeftAngle     float32
	MaxRightAngle    float32
	MaxFrontDistance float32
	MaxRearDistance  float32
	MaxHeight        float32
	MaxWeight        float32
	WarningRate      uint8
	AlarmRate        uint8
	ViolationRate    uint8
}

type RealTimeData struct {
	UploadTimestamp  time.Time
	Height           uint32
	Amplitude        uint32
	Angle            int32
	Load             uint32
	SafeLoadRatio    uint8
	Torque           uint32
	CurrentWindSpeed uint32
	TiltAngleX       int32
	TiltAngleY       int32
	EquipmentStatus  uint32
}

type LiftingData struct {
	UploadTimestamp time.Time
	StartTimestamp  time.Time
	EndTimestamp    time.Time
	MaxLoad         uint32
	MaxTorque       uint32
	StartAngle      int32
	EndAngle        int32
	StartAmplitude  uint32
	EndAmplitude    uint32
	MaxHeight       uint32
	MinHeight       uint32
	MaxWindSpeed    uint32
	TiltAngleX      int32
	TiltAngleY      int32
	EquipmentStatus uint32
}

func parseTimestamp(info []byte) (time.Time, error) {
	if len(info) < 4 {
		return time.Time{}, fmt.Errorf("信息段太短，无法解析时间戳")
	}
	timestamp := binary.BigEndian.Uint32(info[:4])
	return time.Unix(int64(timestamp), 0), nil
}

func parseDeviceAttributes(info []byte) (*DeviceAttributes, error) {
	if len(info) < 88 {
		return nil, fmt.Errorf("信息段太短，无法解析设备属性")
	}

	attributes := &DeviceAttributes{
		SIMCard:          string(info[:20]),
		GroupID:          binary.BigEndian.Uint16(info[20:22]),
		TowerInGroup:     binary.BigEndian.Uint16(info[22:24]),
		RopeRate:         info[24],
		XCoordinate:      float32(binary.BigEndian.Uint32(info[25:29])) / 100,
		YCoordinate:      float32(binary.BigEndian.Uint32(info[29:33])) / 100,
		FrontArmLength:   float32(binary.BigEndian.Uint32(info[33:37])) / 100,
		RearArmLength:    float32(binary.BigEndian.Uint32(info[37:41])) / 100,
		TowerCapHeight:   float32(binary.BigEndian.Uint32(info[41:45])) / 100,
		TowerBodyHeight:  float32(binary.BigEndian.Uint32(info[45:49])) / 100,
		Longitude:        float64(binary.BigEndian.Uint32(info[49:53])) / 1000000,
		Latitude:         float64(binary.BigEndian.Uint32(info[53:57])) / 1000000,
		MaxLeftAngle:     float32(binary.BigEndian.Uint32(info[57:61])) / 100,
		MaxRightAngle:    float32(binary.BigEndian.Uint32(info[61:65])) / 100,
		MaxFrontDistance: float32(binary.BigEndian.Uint32(info[65:69])) / 100,
		MaxRearDistance:  float32(binary.BigEndian.Uint32(info[69:73])) / 100,
		MaxHeight:        float32(binary.BigEndian.Uint32(info[73:77])) / 100,
		MaxWeight:        float32(binary.BigEndian.Uint32(info[77:81])) / 100,
		WarningRate:      info[81],
		AlarmRate:        info[82],
		ViolationRate:    info[83],
	}

	return attributes, nil
}

func parseRealTimeData(info []byte) (*RealTimeData, error) {
	if len(info) < 46 {
		return nil, fmt.Errorf("信息段太短，无法解析实时数据")
	}

	timestamp := binary.BigEndian.Uint32(info[:4])
	height := binary.BigEndian.Uint32(info[4:8])
	amplitude := binary.BigEndian.Uint32(info[8:12])
	angle := int32(binary.BigEndian.Uint32(info[12:16]))
	load := binary.BigEndian.Uint32(info[16:20])
	safeLoadRatio := info[20]
	torque := binary.BigEndian.Uint32(info[21:25])
	windSpeed := binary.BigEndian.Uint32(info[25:29])
	tiltAngleX := int32(binary.BigEndian.Uint32(info[29:33]))
	tiltAngleY := int32(binary.BigEndian.Uint32(info[33:37]))
	equipmentStatus := binary.BigEndian.Uint32(info[37:41])

	return &RealTimeData{
		UploadTimestamp:  time.Unix(int64(timestamp), 0),
		Height:           height,
		Amplitude:        amplitude,
		Angle:            angle,
		Load:             load,
		SafeLoadRatio:    safeLoadRatio,
		Torque:           torque,
		CurrentWindSpeed: windSpeed,
		TiltAngleX:       tiltAngleX,
		TiltAngleY:       tiltAngleY,
		EquipmentStatus:  equipmentStatus,
	}, nil
}

func parseLiftingData(info []byte) (*LiftingData, error) {
	if len(info) < 78 {
		return nil, fmt.Errorf("信息段太短，无法解析吊装数据")
	}

	liftingData := &LiftingData{
		UploadTimestamp: time.Unix(int64(binary.BigEndian.Uint32(info[:4])), 0),
		StartTimestamp:  time.Unix(int64(binary.BigEndian.Uint32(info[4:8])), 0),
		EndTimestamp:    time.Unix(int64(binary.BigEndian.Uint32(info[8:12])), 0),
		MaxLoad:         binary.BigEndian.Uint32(info[12:16]),
		MaxTorque:       binary.BigEndian.Uint32(info[16:20]),
		StartAngle:      int32(binary.BigEndian.Uint32(info[20:24])),
		EndAngle:        int32(binary.BigEndian.Uint32(info[24:28])),
		StartAmplitude:  binary.BigEndian.Uint32(info[28:32]),
		EndAmplitude:    binary.BigEndian.Uint32(info[32:36]),
		MaxHeight:       binary.BigEndian.Uint32(info[36:40]),
		MinHeight:       binary.BigEndian.Uint32(info[40:44]),
		MaxWindSpeed:    binary.BigEndian.Uint32(info[44:48]),
		TiltAngleX:      int32(binary.BigEndian.Uint32(info[48:52])),
		TiltAngleY:      int32(binary.BigEndian.Uint32(info[52:56])),
		EquipmentStatus: binary.BigEndian.Uint32(info[56:60]),
	}

	return liftingData, nil
}
func savetimestamp(db *sql.DB, t time.Time) error {
	query := `
	INSERT INTO time_stamp(time) VALUES (?)`
	_, err := db.Exec(query, t)
	return err
}
func saveDeviceAttributes(db *sql.DB, attributes *DeviceAttributes) error {
	query := `
		INSERT INTO device_attributes (
			sim_card, group_id, tower_in_group, rope_rate, x_coordinate, y_coordinate,
			front_arm_length, rear_arm_length, tower_cap_height, tower_body_height,
			longitude, latitude, max_left_angle, max_right_angle, max_front_distance,
			max_rear_distance, max_height, max_weight, warning_rate, alarm_rate,
			violation_rate
		) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
	`
	_, err := db.Exec(query,
		attributes.SIMCard, attributes.GroupID, attributes.TowerInGroup, attributes.RopeRate,
		attributes.XCoordinate, attributes.YCoordinate, attributes.FrontArmLength, attributes.RearArmLength,
		attributes.TowerCapHeight, attributes.TowerBodyHeight, attributes.Longitude, attributes.Latitude,
		attributes.MaxLeftAngle, attributes.MaxRightAngle, attributes.MaxFrontDistance, attributes.MaxRearDistance,
		attributes.MaxHeight, attributes.MaxWeight, attributes.WarningRate, attributes.AlarmRate, attributes.ViolationRate,
	)
	if err != nil {
		log.Printf("保存设备属性信息失败: %v", err)
	}
	return err
}

func saveRealTimeData(db *sql.DB, data *RealTimeData) error {
	query := `
		INSERT INTO real_time_data (
			upload_timestamp, height, amplitude, angle, load1, safe_load_ratio,
			torque, current_wind_speed, tilt_angle_x, tilt_angle_y, equipment_status
		) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
	`
	_, err := db.Exec(query,
		data.UploadTimestamp, data.Height, data.Amplitude, data.Angle, data.Load,
		data.SafeLoadRatio, data.Torque, data.CurrentWindSpeed, data.TiltAngleX, data.TiltAngleY,
		data.EquipmentStatus,
	)
	if err != nil {
		log.Printf("保存实时数据失败: %v", err)
	}
	return err
}

func saveLiftingData(db *sql.DB, data *LiftingData) error {
	query := `
		INSERT INTO lifting_data (
			upload_timestamp, start_timestamp, end_timestamp, max_load, max_torque,
			start_angle, end_angle, start_amplitude, end_amplitude, max_height,
			min_height, max_wind_speed, tilt_angle_x, tilt_angle_y, equipment_status
		) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
	`
	_, err := db.Exec(query,
		data.UploadTimestamp, data.StartTimestamp, data.EndTimestamp, data.MaxLoad, data.MaxTorque,
		data.StartAngle, data.EndAngle, data.StartAmplitude, data.EndAmplitude, data.MaxHeight,
		data.MinHeight, data.MaxWindSpeed, data.TiltAngleX, data.TiltAngleY, data.EquipmentStatus,
	)
	if err != nil {
		log.Printf("保存吊装数据失败: %v", err)
	}
	return err
}

// 解析数据帧
func parseFrame(data []byte) (*Frame, error) {
	if len(data) < 14 { // Minimum frame length
		return nil, fmt.Errorf("数据太短")
	}

	header := binary.BigEndian.Uint16(data[0:2])
	if header != FrameHeader {
		return nil, fmt.Errorf("无效的帧头: %x", header)
	}

	length := data[2]
	expectedLength := int(length) // Length includes the entire frame length
	if len(data) != expectedLength {
		return nil, fmt.Errorf("无效的数据长度: 期望 %d, 实际 %d", expectedLength, len(data))
	}

	tail := binary.BigEndian.Uint32(data[len(data)-4:])
	if tail != FrameTail {
		return nil, fmt.Errorf("无效的帧尾: %x", tail)
	}

	frame := &Frame{
		Header:       header,
		Length:       length,
		Manufacturer: data[3],
		Version:      data[4],
		FrameType:    data[5],
	}
	copy(frame.DeviceID[:], data[6:10])
	frame.Info = data[10 : len(data)-5]
	frame.Checksum = data[len(data)-5]
	frame.Tail = tail

	return frame, nil
}

// 处理WebSocket连接
func handleWebSocket(w http.ResponseWriter, r *http.Request) {
	ws, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Fatal(err)
	}
	defer ws.Close()

	clients[ws] = true

	for {
		_, msg, err := ws.ReadMessage()
		if err != nil {
			log.Println("WebSocket读取数据失败:", err)
			delete(clients, ws)
			break
		}
		if string(msg) == "read_device_registration" {
			handleDBReadDeviceRegistration(ws, db)
		} else if string(msg) == "read_device_attributes" {
			handleDBReadDeviceAttributes(ws, db)
		} else if string(msg) == "read_real_time_data" {
			handleDBReadRealTimeData(ws, db)
		} else if string(msg) == "read_lifting_data" {
			handleDBReadLiftingData(ws, db)
		} else {
			broadcast <- msg
		}
	}
}

// 处理来自TCP服务器的数据
func handleTCPData(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		http.Error(w, "仅支持POST方法", http.StatusMethodNotAllowed)
		return
	}

	data, err := ioutil.ReadAll(r.Body)
	if err != nil {
		http.Error(w, "读取请求体失败", http.StatusInternalServerError)
		return
	}

	// 记录接收到的数据
	log.Printf("收到来自TCP服务器的数据: %s\n", hex.EncodeToString(data))

	// 检查数据是否为空
	if len(data) == 0 {
		log.Println("接收到空数据")
		http.Error(w, "接收到空数据", http.StatusBadRequest)
		return
	}

	broadcast <- data
	w.WriteHeader(http.StatusOK)
}

// 处理TCP客户端连接
func handleClient(conn net.Conn, db *sql.DB) {
	defer conn.Close()

	for {
		// 从客户端读取
		buffer := make([]byte, 1024)
		n, err := conn.Read(buffer)
		if err != nil {
			log.Println("读取数据失败:", err)
			break
		}

		// 输出从客户端接收到的数据
		fmt.Printf("收到客户端数据: %s\n", hex.EncodeToString(buffer[:n]))

		// 解析数据帧
		frame, err := parseFrame(buffer[:n])
		if err != nil {
			log.Println("解析数据失败:", err)
			continue
		}

		// 打印解析后的数据帧信息
		fmt.Printf("帧头: 0x%x\n", frame.Header)
		fmt.Printf("长度: %d\n", frame.Length)
		fmt.Printf("厂家编号: 0x%x\n", frame.Manufacturer)
		fmt.Printf("协议版本: 0x%x\n", frame.Version)
		fmt.Printf("帧类型: 0x%x\n", frame.FrameType)
		fmt.Printf("设备编号: %x\n", frame.DeviceID)
		fmt.Printf("帧尾: 0x%x\n", frame.Tail)

		// 根据帧类型处理数据
		switch frame.FrameType {
		case 0x00: // 设备注册请求帧
			timestamp, err := parseTimestamp(frame.Info)
			if err != nil {
				log.Println("解析时间戳失败:", err)
				continue
			} else {
				fmt.Printf("解析的时间戳: %s\n", timestamp.Format(time.RFC3339))
				err = savetimestamp(db, timestamp)
				if err != nil {
					log.Println("保存设备属性信息失败:", err)
				}
			}
		case 0x02: // 设备参数上报请求帧
			attributes, err := parseDeviceAttributes(frame.Info)
			if err != nil {
				log.Println("解析设备属性信息失败:", err)
			} else {
				// 打印设备属性信息
				fmt.Printf("SIM卡号: %s\n", attributes.SIMCard)
				fmt.Printf("群塔ID: %d\n", attributes.GroupID)
				fmt.Printf("塔机在群: %d\n", attributes.TowerInGroup)
				fmt.Printf("吊绳倍率: %d\n", attributes.RopeRate)
				fmt.Printf("X坐标: %.2f\n", attributes.XCoordinate)
				fmt.Printf("Y坐标: %.2f\n", attributes.YCoordinate)
				fmt.Printf("前臂长度: %.2f\n", attributes.FrontArmLength)
				fmt.Printf("后臂长度: %.2f\n", attributes.RearArmLength)
				fmt.Printf("塔帽高度: %.2f\n", attributes.TowerCapHeight)
				fmt.Printf("塔身高度: %.2f\n", attributes.TowerBodyHeight)
				fmt.Printf("经度: %.6f\n", attributes.Longitude)
				fmt.Printf("纬度: %.6f\n", attributes.Latitude)
				fmt.Printf("左转最大角度: %.2f\n", attributes.MaxLeftAngle)
				fmt.Printf("右转最大角度: %.2f\n", attributes.MaxRightAngle)
				fmt.Printf("前行最远距离: %.2f\n", attributes.MaxFrontDistance)
				fmt.Printf("回收最近距离: %.2f\n", attributes.MaxRearDistance)
				fmt.Printf("最高高度: %.2f\n", attributes.MaxHeight)
				fmt.Printf("最大起重量: %.2f\n", attributes.MaxWeight)
				fmt.Printf("预警百分比: %d\n", attributes.WarningRate)
				fmt.Printf("报警百分比: %d\n", attributes.AlarmRate)
				fmt.Printf("违章百分比: %d\n", attributes.ViolationRate)

				// 保存设备属性信息到数据库
				err = saveDeviceAttributes(db, attributes)
				if err != nil {
					log.Println("保存设备属性信息失败:", err)
				}
			}
		case 0x06: // 实时数据上报请求帧
			realTimeData, err := parseRealTimeData(frame.Info)
			if err != nil {
				log.Println("解析实时数据失败:", err)
			} else {
				// 打印实时数据
				fmt.Printf("上传时间戳: %s\n", realTimeData.UploadTimestamp.Format(time.RFC3339))
				fmt.Printf("高度: %d\n", realTimeData.Height)
				fmt.Printf("幅度: %d\n", realTimeData.Amplitude)
				fmt.Printf("转角: %.2f\n", float32(realTimeData.Angle)/100)
				fmt.Printf("载重: %d\n", realTimeData.Load)
				fmt.Printf("安全载重比: %d%%\n", realTimeData.SafeLoadRatio)
				fmt.Printf("力矩: %d\n", realTimeData.Torque)
				fmt.Printf("当前风速: %d\n", realTimeData.CurrentWindSpeed)
				fmt.Printf("倾斜角度X: %.2f\n", float32(realTimeData.TiltAngleX)/100)
				fmt.Printf("倾斜角度Y: %.2f\n", float32(realTimeData.TiltAngleY)/100)
				fmt.Printf("设备状态: %d\n", realTimeData.EquipmentStatus)

				// 保存实时数据到数据库
				err = saveRealTimeData(db, realTimeData)
				if err != nil {
					log.Println("保存实时数据失败:", err)
				}
			}
		case 0x08: // 吊装数据上报请求帧
			liftingData, err := parseLiftingData(frame.Info)
			if err != nil {
				log.Println("解析吊装数据失败:", err)
			} else {
				// 打印吊装数据
				fmt.Printf("上传时间戳: %s\n", liftingData.UploadTimestamp.Format(time.RFC3339))
				fmt.Printf("吊装开始时间戳: %s\n", liftingData.StartTimestamp.Format(time.RFC3339))
				fmt.Printf("吊装结束时间戳: %s\n", liftingData.EndTimestamp.Format(time.RFC3339))
				fmt.Printf("最大载重: %d\n", liftingData.MaxLoad)
				fmt.Printf("最大力矩: %d\n", liftingData.MaxTorque)
				fmt.Printf("开始转角: %.2f\n", float32(liftingData.StartAngle)/100)
				fmt.Printf("结束转角: %.2f\n", float32(liftingData.EndAngle)/100)
				fmt.Printf("开始幅度: %d\n", liftingData.StartAmplitude)
				fmt.Printf("结束幅度: %d\n", liftingData.EndAmplitude)
				fmt.Printf("最大起升高度: %d\n", liftingData.MaxHeight)
				fmt.Printf("最小起升高度: %d\n", liftingData.MinHeight)
				fmt.Printf("最大风速: %d\n", liftingData.MaxWindSpeed)
				fmt.Printf("倾角X: %.2f\n", float32(liftingData.TiltAngleX)/100)
				fmt.Printf("倾角Y: %.2f\n", float32(liftingData.TiltAngleY)/100)
				fmt.Printf("设备状态: %d\n", liftingData.EquipmentStatus)

				// 保存吊装数据到数据库
				err = saveLiftingData(db, liftingData)
				if err != nil {
					log.Println("保存吊装数据失败:", err)
				}
			}
		default:
			fmt.Println("未知帧类型:", frame.FrameType)
		}

		// 将数据发送到WebSocket服务器
		err = sendToWebSocketServer(buffer[:n])
		if err != nil {
			log.Println("发送数据到WebSocket服务器失败:", err)
		}

		// 将接收到的数据发送回客户端
		_, err = conn.Write(buffer[:n])
		if err != nil {
			log.Println("发送数据失败:", err)
			break
		}
	}
}

// 发送数据到WebSocket服务器
func sendToWebSocketServer(data []byte) error {
	url := "http://localhost:8080/tcpdata" // WebSocket服务器的实际地址
	req, err := http.NewRequest("POST", url, bytes.NewBuffer(data))
	if err != nil {
		return err
	}
	req.Header.Set("Content-Type", "application/octet-stream")

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("非预期的HTTP状态码: %d", resp.StatusCode)
	}
	return nil
}

// 从数据库中读取设备注册数据并发送到WebSocket客户端
func handleDBReadDeviceRegistration(ws *websocket.Conn, db *sql.DB) {
	rows, err := db.Query("SELECT * FROM time_stamp")
	if err != nil {
		log.Printf("查询数据库失败: %v", err)
		return
	}
	defer rows.Close()

	for rows.Next() {
		var timestamp string
		err := rows.Scan(&timestamp)
		if err != nil {
			log.Printf("扫描数据库行失败: %v", err)
			continue
		}

		// 将字符串转换为时间类型
		parsedTimestamp, err := time.Parse("2006-01-02 15:04:05", timestamp)
		if err != nil {
			log.Printf("解析时间戳失败: %v", err)
			continue
		}

		// 将数据发送到WebSocket客户端
		err = ws.WriteJSON(map[string]interface{}{
			"timestamp": parsedTimestamp,
		})
		if err != nil {
			log.Printf("发送数据到WebSocket客户端失败: %v", err)
			break
		}
	}
}

// 从数据库中读取设备属性数据并发送到WebSocket客户端
func handleDBReadDeviceAttributes(ws *websocket.Conn, db *sql.DB) {
	rows, err := db.Query("SELECT * FROM device_attributes")
	if err != nil {
		log.Printf("查询数据库失败: %v", err)
		return
	}
	defer rows.Close()

	for rows.Next() {
		var attributes DeviceAttributes
		err := rows.Scan(&attributes.SIMCard, &attributes.GroupID, &attributes.TowerInGroup, &attributes.RopeRate,
			&attributes.XCoordinate, &attributes.YCoordinate, &attributes.FrontArmLength, &attributes.RearArmLength,
			&attributes.TowerCapHeight, &attributes.TowerBodyHeight, &attributes.Longitude, &attributes.Latitude,
			&attributes.MaxLeftAngle, &attributes.MaxRightAngle, &attributes.MaxFrontDistance, &attributes.MaxRearDistance,
			&attributes.MaxHeight, &attributes.MaxWeight, &attributes.WarningRate, &attributes.AlarmRate, &attributes.ViolationRate)
		if err != nil {
			log.Printf("扫描数据库行失败: %v", err)
			continue
		}

		// 将数据发送到WebSocket客户端
		err = ws.WriteJSON(attributes)
		if err != nil {
			log.Printf("发送数据到WebSocket客户端失败: %v", err)
			break
		}
	}
}

// 从数据库中读取实时数据并发送到WebSocket客户端
func handleDBReadRealTimeData(ws *websocket.Conn, db *sql.DB) {
	rows, err := db.Query("SELECT upload_timestamp, height, amplitude, angle, load1, safe_load_ratio, torque, current_wind_speed, tilt_angle_x, tilt_angle_y, equipment_status FROM real_time_data")
	if err != nil {
		log.Printf("查询数据库失败: %v", err)
		return
	}
	defer rows.Close()

	for rows.Next() {
		var uploadTimestamp string
		var data RealTimeData
		err := rows.Scan(&uploadTimestamp, &data.Height, &data.Amplitude, &data.Angle, &data.Load,
			&data.SafeLoadRatio, &data.Torque, &data.CurrentWindSpeed, &data.TiltAngleX, &data.TiltAngleY, &data.EquipmentStatus)
		if err != nil {
			log.Printf("扫描数据库行失败: %v", err)
			continue
		}

		// 将字符串转换为时间类型
		data.UploadTimestamp, err = time.Parse("2006-01-02 15:04:05", uploadTimestamp)
		if err != nil {
			log.Printf("解析时间戳失败: %v", err)
			continue
		}

		// 将数据发送到WebSocket客户端
		err = ws.WriteJSON(data)
		if err != nil {
			log.Printf("发送数据到WebSocket客户端失败: %v", err)
			break
		}
	}
}

// 从数据库中读取吊装数据并发送到WebSocket客户端
func handleDBReadLiftingData(ws *websocket.Conn, db *sql.DB) {
	rows, err := db.Query("SELECT upload_timestamp, start_timestamp, end_timestamp, max_load, max_torque, start_angle, end_angle, start_amplitude, end_amplitude, max_height, min_height, max_wind_speed, tilt_angle_x, tilt_angle_y, equipment_status FROM lifting_data")
	if err != nil {
		log.Printf("查询数据库失败: %v", err)
		return
	}
	defer rows.Close()

	for rows.Next() {
		var uploadTimestamp, startTimestamp, endTimestamp string
		var data LiftingData
		err := rows.Scan(&uploadTimestamp, &startTimestamp, &endTimestamp, &data.MaxLoad, &data.MaxTorque,
			&data.StartAngle, &data.EndAngle, &data.StartAmplitude, &data.EndAmplitude, &data.MaxHeight,
			&data.MinHeight, &data.MaxWindSpeed, &data.TiltAngleX, &data.TiltAngleY, &data.EquipmentStatus)
		if err != nil {
			log.Printf("扫描数据库行失败: %v", err)
			continue
		}

		// 将字符串转换为时间类型
		data.UploadTimestamp, err = time.Parse("2006-01-02 15:04:05", uploadTimestamp)
		if err != nil {
			log.Printf("解析上传时间戳失败: %v", err)
			continue
		}
		data.StartTimestamp, err = time.Parse("2006-01-02 15:04:05", startTimestamp)
		if err != nil {
			log.Printf("解析开始时间戳失败: %v", err)
			continue
		}
		data.EndTimestamp, err = time.Parse("2006-01-02 15:04:05", endTimestamp)
		if err != nil {
			log.Printf("解析结束时间戳失败: %v", err)
			continue
		}

		// 将数据发送到WebSocket客户端
		err = ws.WriteJSON(data)
		if err != nil {
			log.Printf("发送数据到WebSocket客户端失败: %v", err)
			break
		}
	}
}

const (
	dbUser     = "root"
	dbPassword = "cx2002114"
	dbName     = "db1"
)

var db *sql.DB

func initDB() {
	var err error
	dsn := dbUser + ":" + dbPassword + "@/" + dbName
	db, err = sql.Open("mysql", dsn)
	if err != nil {
		log.Fatalf("Error opening database: %v", err)
	}
	if err = db.Ping(); err != nil {
		log.Fatalf("Error connecting to database: %v", err)
	}
}

func main() {
	// 设置数据库连接
	initDB()
	defer db.Close()

	go func() {
		http.HandleFunc("/ws", handleWebSocket)
		http.HandleFunc("/tcpdata", handleTCPData)

		go func() {
			for {
				msg := <-broadcast
				for client := range clients {
					err := client.WriteMessage(websocket.TextMessage, msg)
					if err != nil {
						log.Printf("WebSocket发送数据失败: %v", err)
						client.Close()
						delete(clients, client)
					}
				}
			}
		}()

		log.Println("WebSocket服务器启动，监听 8080 端口...")
		log.Fatal(http.ListenAndServe("localhost:8080", nil))
	}()

	// 设置服务器监听的地址和端口
	listener, err := net.Listen("tcp", ":5050")
	if err != nil {
		log.Fatal("监听失败:", err)
	}
	defer listener.Close()

	fmt.Println("服务器启动，监听 5050 端口...")

	// 接受连接
	for {
		conn, err := listener.Accept()
		if err != nil {
			log.Println("接受连接失败:", err)
			continue
		}

		// 为每个连接创建一个 goroutine 来处理
		go handleClient(conn, db)
	}
}
